package com.campus.lostandfound.controller;

import com.campus.lostandfound.common.Result;
import com.campus.lostandfound.entity.Role;
import com.campus.lostandfound.entity.User;
import com.campus.lostandfound.service.AdminService;
import com.campus.lostandfound.service.UserService;
import com.campus.lostandfound.service.VerifyCodeService;
import com.campus.lostandfound.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户Controller
 */
@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private VerifyCodeService verifyCodeService;
    
    @Autowired
    private AdminService adminService;
    
    /**
     * 用户注册
     */
    @PostMapping("/register")
    public Result<String> register(@RequestBody User user) {
        try {
            userService.register(user);
            return Result.success("注册成功");
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 用户登录
     */
    @PostMapping("/login")
    public Result<Map<String, Object>> login(@RequestBody Map<String, String> params) {
        try {
            String username = params.get("username");
            String password = params.get("password");
            
            User user = userService.login(username, password);
            
            // 生成Token
            String token = jwtUtil.generateToken(user.getUserId(), user.getUsername(), user.getRole());
            
            // 获取用户的 RBAC 角色
            List<Role> roles = adminService.getUserRoles(user.getId());
            List<String> roleCodes = roles.stream()
                    .map(Role::getRoleCode)
                    .collect(Collectors.toList());
            
            // 返回用户信息和Token
            Map<String, Object> data = new HashMap<>();
            data.put("token", token);
            data.put("userId", user.getUserId());
            data.put("username", user.getUsername());
            data.put("role", user.getRole());
            data.put("phone", user.getPhone());
            data.put("email", user.getEmail());
            data.put("roles", roleCodes); // RBAC 角色代码列表
            
            return Result.success("登录成功", data);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 获取当前用户信息
     */
    @GetMapping("/info")
    public Result<User> getUserInfo(@RequestHeader("Authorization") String token) {
        try {
            String userId = jwtUtil.getUserIdFromToken(token);
            User user = userService.getUserByUserId(userId);
            
            // 清除敏感信息
            user.setPassword(null);
            user.setSalt(null);
            
            return Result.success(user);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 测试缓存功能（连续3次查询同一用户）
     */
    @GetMapping("/test-cache")
    public Result<Map<String, Object>> testCache(@RequestHeader("Authorization") String token) {
        try {
            String userId = jwtUtil.getUserIdFromToken(token);
            
            System.out.println("========================================");
            System.out.println("开始测试Redis缓存功能");
            System.out.println("用户ID: " + userId);
            System.out.println("========================================");
            
            long start1 = System.currentTimeMillis();
            System.out.println("\n【第1次查询】调用 getUserByUserId...");
            User user1 = userService.getUserByUserId(userId);
            long time1 = System.currentTimeMillis() - start1;
            System.out.println("【第1次查询】耗时: " + time1 + "ms");
            
            long start2 = System.currentTimeMillis();
            System.out.println("\n【第2次查询】调用 getUserByUserId...");
            User user2 = userService.getUserByUserId(userId);
            long time2 = System.currentTimeMillis() - start2;
            System.out.println("【第2次查询】耗时: " + time2 + "ms");
            
            long start3 = System.currentTimeMillis();
            System.out.println("\n【第3次查询】调用 getUserByUserId...");
            User user3 = userService.getUserByUserId(userId);
            long time3 = System.currentTimeMillis() - start3;
            System.out.println("【第3次查询】耗时: " + time3 + "ms");
            
            System.out.println("\n========================================");
            System.out.println("缓存测试完成");
            System.out.println("第1次（数据库）: " + time1 + "ms");
            System.out.println("第2次（缓存）  : " + time2 + "ms");
            System.out.println("第3次（缓存）  : " + time3 + "ms");
            System.out.println("性能提升: " + ((time1 - time2) * 100 / time1) + "%");
            System.out.println("========================================\n");
            
            Map<String, Object> result = new HashMap<>();
            result.put("userId", userId);
            result.put("username", user1.getUsername());
            result.put("第1次耗时(ms)", time1);
            result.put("第2次耗时(ms)", time2);
            result.put("第3次耗时(ms)", time3);
            result.put("性能提升", ((time1 - time2) * 100 / time1) + "%");
            result.put("说明", "第1次查询数据库，第2-3次从Redis缓存读取");
            
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 修改密码
     */
    @PostMapping("/changePassword")
    public Result<String> changePassword(@RequestHeader("Authorization") String token,
                                         @RequestBody Map<String, String> params) {
        try {
            String userId = jwtUtil.getUserIdFromToken(token);
            String oldPassword = params.get("oldPassword");
            String newPassword = params.get("newPassword");
            
            userService.changePassword(userId, oldPassword, newPassword);
            return Result.success("密码修改成功");
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 发送验证码（忘记密码 - 第一步）
     */
    @PostMapping("/sendVerifyCode")
    public Result<Map<String, Object>> sendVerifyCode(@RequestBody Map<String, String> params) {
        try {
            String phone = params.get("phone");
            
            // 验证手机号是否存在
            User user = userService.getUserByPhone(phone);
            
            // 发送验证码
            String code = verifyCodeService.sendVerifyCode(phone);
            
            // 返回脱敏的手机号和用户名（提示用户）
            Map<String, Object> data = new HashMap<>();
            data.put("phone", maskPhone(phone));
            data.put("username", user.getUsername());
            // 开发环境下返回验证码（方便测试，生产环境应该删除）
            data.put("code", code);
            
            return Result.success("验证码已发送，请查看控制台", data);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 验证验证码（忘记密码 - 第二步）
     */
    @PostMapping("/verifyCode")
    public Result<String> verifyCode(@RequestBody Map<String, String> params) {
        try {
            String phone = params.get("phone");
            String code = params.get("code");
            
            verifyCodeService.verifyCode(phone, code);
            return Result.success("验证码正确");
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 重置密码（忘记密码 - 第三步）
     */
    @PostMapping("/resetPassword")
    public Result<String> resetPassword(@RequestBody Map<String, String> params) {
        try {
            String phone = params.get("phone");
            String code = params.get("code");
            String newPassword = params.get("newPassword");
            
            // 再次验证验证码
            verifyCodeService.verifyCode(phone, code);
            
            // 重置密码
            userService.resetPasswordByPhone(phone, newPassword);
            
            // 清除验证码
            verifyCodeService.clearCode(phone);
            
            return Result.success("密码重置成功，请使用新密码登录");
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 手机号脱敏
     */
    private String maskPhone(String phone) {
        if (phone == null || phone.length() != 11) {
            return phone;
        }
        return phone.substring(0, 3) + "****" + phone.substring(7);
    }
}

